package com.mylater.nace.compiler;

import javax.tools.JavaCompiler.CompilationTask;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * ClassFileManager
 * Description:
 * CreateDate: 2018/8/24 16:59
 *
 * @author HaoJie
 */
public class ClassCompiler {

    /**
     * java文件的存放路径
     */
    public final static String JAVA_FILES_PATH = System.getProperty("user.dir") + "/Client/src/test/java/";

    private final static ClassCompiler compiler = new ClassCompiler();

    /**
     * @param javaFileNames 类的全限定名称
     * @return
     */
    public static byte[] callJavac(String... javaFileNames) {
        return callJavac(null, javaFileNames);
    }

    /**
     * @param options       其他参数，已有参数包括"-verbose"
     * @param javaFileNames 类的全限定名称
     * @return
     */
    public static byte[] callJavac(List<String> options, String... javaFileNames) {
        // standardJavaFileManager实际类型 : com.sun.tools.javac.file.JavacFileManager
        javax.tools.StandardJavaFileManager javaFileManager = null;
        ExJavaFileManager exJavaFileManager = null;
        try {
            // compiler实际类型:com.sun.tools.javac.api.JavacTool
            javax.tools.JavaCompiler javaCompiler = javax.tools.ToolProvider.getSystemJavaCompiler();
            javaFileManager = javaCompiler.getStandardFileManager(null, null, null);
            exJavaFileManager = new ExJavaFileManager(javaFileManager);

            for (int i = 0; i < javaFileNames.length; ++i) {
                javaFileNames[i] = JAVA_FILES_PATH + javaFileNames[i].replace(".", "/") + ".java";
            }
            Iterable<? extends javax.tools.JavaFileObject> javaFileObjects = javaFileManager.getJavaFileObjects(javaFileNames);
            // 相当于命令行调用javac时的参数
            List<String> args = new ArrayList<String>();
            args.add("-verbose");
            if (options != null) {
                for (String arg : options) {
                    args.add(arg);
                }
            }
            CompilationTask compilerTask = javaCompiler.getTask(null, exJavaFileManager, null, args, null, javaFileObjects);
            // 编译，调用com.sun.tools.javac.main.compile(String[], Context, List<JavaFileObject>, Iterable<? extends Processor>)
            if (compilerTask.call()) {
                return exJavaFileManager.getJavaClassObject().getBytes();
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (javaFileManager != null)
                try {
                    javaFileManager.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            if (exJavaFileManager != null)
                try {
                    exJavaFileManager.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
        return null;
    }

}
